package com.touchportfolio.loadQueue.loaders
{
	import com.touchportfolio.events.ErrorEvent;
	import com.touchportfolio.events.PayloadEvent;
	import com.touchportfolio.loadQueue.IQueueLoader;
	
	import flash.events.AsyncErrorEvent;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.NetStatusEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.NetConnection;
	import flash.net.Responder;

	/**
	 * The AMFCaller class is used to make AMFCalls and store the result in an array<br>
	 * The condition to make it work is that your gateway is right and that your class/function exists<br>
	 * The result can be found in 'data'<br><br>
	 * This class dispatches an ErrorEvent.ERROR with all the different errors that occured
	 **/
	
	public class AMFCaller extends EventDispatcher implements IQueueLoader
	{	
		private var _nc:NetConnection;
      	private var _data:*;
		private var _function:String;
		private var _args:Array;
		private var _gateway:String;
		
		/**
		 * Contains the result of the amfcall
		 * @return an array with the results of the amfcall
		 **/
		 
		public function get data():*
		{
			return _data;
		}
		
		/**
		 * This is the constructor of the AMFCaller class
		 * @param classDotFunction is a string with the class and the function that has to be executed
		 * @param args is an array with all the different arguments that you would like to send to the PHP function @default null
		 **/
		
		public function AMFCaller(classDotFunction:String, gateway:String, args:Array = null)
		{
			_function = classDotFunction;
			_gateway = gateway;
			_args = args;
		}
		
		/**
		 * This function is used to begin the actual process. It will make a connection and make the call
		 **/
		
		public function run():void
		{
			_nc = new NetConnection();
			_nc.connect(_gateway);
			_nc.addEventListener(IOErrorEvent.IO_ERROR, IOErrorHandler);
			_nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR, AsyncErrorHandler);
			_nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, SecurityErrorHandler);
			_nc.addEventListener(NetStatusEvent.NET_STATUS, NetStatusHandler);
			var args:Array = [_function, new Responder(onResult, onFault)].concat(_args);
			_nc.call.apply(this, args);
		}
		
		private function onResult(responds:*):void
		{
			_data = responds;
			dispatchEvent(new PayloadEvent(_data, PayloadEvent.PAYLOAD));
			dispatchEvent(new Event(Event.COMPLETE));
			_nc.close();
		}
		
		private function onFault(responds:Object):void
		{
			var faults:Array = [];		
			for(var i:int = 0; i < responds.length; i++)
			{
				faults.push(responds);
			}	
			dispatchEvent(new ErrorEvent(["These errors occurred while running the function \""+_function+"\" : "+faults.toString()], ErrorEvent.ERROR));
		}
		
		private function IOErrorHandler(e:IOErrorEvent):void
		{
			dispatchEvent(new ErrorEvent(["IO error occurred while running the function \""+_function+"\""], ErrorEvent.ERROR));
		}
		
		private function AsyncErrorHandler(e:IOErrorEvent):void
		{
			dispatchEvent(new ErrorEvent(["Asynchronous errors occurred while running the function \""+_function+"\""], ErrorEvent.ERROR));
		}
		
		private function SecurityErrorHandler(e:SecurityErrorEvent):void
		{
			dispatchEvent(new ErrorEvent(["Security errors occurred while running the function \""+_function+"\""], ErrorEvent.ERROR));
		}
		
		private function NetStatusHandler(e:NetStatusEvent):void
		{
			if(e.info.level == "error")
			{
				dispatchEvent(new ErrorEvent(["NetStatus error occurred while running the function \""+_function+"\", this could be a problem with the gateway or the link to the gateway"], ErrorEvent.ERROR));
			}
		}
		
	}
}